from flask import Blueprint, render_template, redirect, url_for, session, g, flash
from .forms import LoginForm
from flask import request
from models import Teacher, Student
from werkzeug.security import generate_password_hash, check_password_hash
import time
from datetime import datetime, timedelta

# password = generate_password_hash(password) 加密
bp = Blueprint("login", __name__, url_prefix="/")

# 登录尝试记录 - 简单的内存存储（生产环境应使用Redis或数据库）
login_attempts = {}


@bp.route("/layout")
def layout():
    session.clear()
    setattr(g, "user", None)
    return redirect(url_for('login.login'))


def check_login_attempts(user_id):
    """检查登录尝试次数"""
    current_time = datetime.now()
    user_id_str = str(user_id)
    
    if user_id_str in login_attempts:
        attempts_data = login_attempts[user_id_str]
        # 如果距离上次失败登录超过15分钟，重置计数
        if current_time - attempts_data['last_attempt'] > timedelta(minutes=15):
            del login_attempts[user_id_str]
            return True
        # 如果失败次数超过5次且在15分钟内，禁止登录
        if attempts_data['count'] >= 5:
            return False
    return True

def record_failed_attempt(user_id):
    """记录失败的登录尝试"""
    user_id_str = str(user_id)
    current_time = datetime.now()
    
    if user_id_str in login_attempts:
        login_attempts[user_id_str]['count'] += 1
        login_attempts[user_id_str]['last_attempt'] = current_time
    else:
        login_attempts[user_id_str] = {
            'count': 1,
            'last_attempt': current_time
        }

def clear_login_attempts(user_id):
    """清除登录尝试记录"""
    user_id_str = str(user_id)
    if user_id_str in login_attempts:
        del login_attempts[user_id_str]

@bp.route("/", methods=['GET', 'POST'])
def login():
    if request.method == 'GET':
        return render_template('index.html')
    else:
        form = LoginForm(request.form)
        if form.validate():
            ID = form.ID.data
            password = form.password.data
            
            # 检查登录尝试次数
            if not check_login_attempts(ID):
                flash('登录失败次数过多，请15分钟后再试')
                return redirect(url_for('login.login'))
            
            # 首先查找教师
            user = Teacher.query.filter_by(ID=ID).first()
            user_role = 'teacher'
            
            # 如果不是教师，查找学生
            if user is None:
                user = Student.query.filter_by(ID=ID).first()
                user_role = 'student'
                
            if user is None:
                record_failed_attempt(ID)
                flash('用户不存在')
                return redirect(url_for('login.login'))
            
            # 验证密码
            if check_password_hash(user.password, password):
                # 登录成功，清除失败记录
                clear_login_attempts(ID)
                
                # 清理旧的session
                session.clear()
                
                # 设置新的session
                session['is_login'] = 'true'
                session['user_id'] = user.ID
                session['user_name'] = user.name
                session['role'] = user_role
                session['login_time'] = datetime.now().isoformat()
                
                # 为学生设置班级信息
                if user_role == 'student':
                    session['class_id1'] = user.class_id1
                    session['class_id2'] = user.class_id2
                
                setattr(g, "user", user)
                
                # 根据用户角色重定向到对应页面
                if user_role == 'student':
                    return redirect("/student/")  # 重定向到学生主框架页面
                else:
                    return redirect("/teacher")
            else:
                record_failed_attempt(ID)
                flash('密码错误')
                return redirect(url_for('login.login'))
        else:
            # 表单验证失败
            for field, errors in form.errors.items():
                for error in errors:
                    flash(f'{field}: {error}')
            return redirect(url_for('login.login'))

@bp.route("/logout")
def logout():
    """安全退出登录"""
    user_id = session.get('user_id')
    if user_id:
        # 记录退出日志
        print(f"用户 {user_id} 退出登录")
    
    # 清除所有session数据
    session.clear()
    setattr(g, "user", None)
    flash('您已安全退出')
    return redirect(url_for('login.login'))

@bp.route("/check_session")
def check_session():
    """检查会话有效性"""
    if session.get('is_login') != 'true':
        return jsonify({'valid': False, 'message': '会话已失效'})
    
    # 检查会话是否过期（可选，设置会话超时时间）
    login_time_str = session.get('login_time')
    if login_time_str:
        try:
            login_time = datetime.fromisoformat(login_time_str)
            # 设置8小时会话超时
            if datetime.now() - login_time > timedelta(hours=8):
                session.clear()
                return jsonify({'valid': False, 'message': '会话已超时'})
        except:
            session.clear()
            return jsonify({'valid': False, 'message': '会话数据异常'})
    
    return jsonify({
        'valid': True, 
        'user_id': session.get('user_id'),
        'role': session.get('role'),
        'user_name': session.get('user_name')
    })
